﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using YJKRGeometry;
using ModelCheckUtility.Properties;

namespace ModelCheckUtility.ModelLayer
{
	public class BaseCloseCurvePacker : ICloseCurveAnalays, IResultPackerTag
	{
		public double AppendValue { get; set; }

		public string RoomType { get; set; }

		public string BuildingType { get; set; }

		public BaseCloseCurvePacker(Element inputElement, List<Curve> lstBoundaryCurves, List<BaseDoorPacker> lstDoorPackers)
		{
			this.m_thisElement = inputElement;
			if (this.m_thisElement is SpatialElement)
			{
				this.m_dThisArea = (this.m_thisElement as SpatialElement).Area;
			}
			else
			{
				Parameter parameter = inputElement.get_Parameter((BuiltInParameter)Enum.Parse(typeof(BuiltInParameter), Resources.Str_ParameterBuitlIn_Area));
				if (parameter == null)
				{
					foreach (Parameter parameter2 in inputElement.GetParameters(Resources.Str_ParametetName_Area))
					{
                        if (2 == (int)parameter2.StorageType)
						{
							parameter = parameter2;
							break;
						}
					}
				}
				if (parameter != null)
				{
					this.m_dThisArea = parameter.AsDouble();
				}
				else
				{
					this.m_dThisArea = 0.0;
				}
			}
			this.m_lstCurves = lstBoundaryCurves;
			this.m_thisLocationPoint = Utility.CalculateLstCurveMidPoint(this.m_lstCurves);
			this.m_lstDoorPackers = lstDoorPackers;
			if (this.m_lstDoorPackers != null)
			{
				this.AnalyseNearRooms();
			}
		}

		public List<BaseDoorPacker> GetAllDoors()
		{
			return this.m_lstDoorPackers;
		}

		public List<BaseRoomPacker> GetNearRooms()
		{
			return this.m_lstNearRoomPackers;
		}

		public List<Curve> GetAllBoundaryCurves()
		{
			return this.m_lstCurves;
		}

		public double GetArea()
		{
			return this.m_dThisArea;
		}

		public Element GetThisElement()
		{
			return this.m_thisElement;
		}

		private void AnalyseNearRooms()
		{
			this.m_lstNearRoomPackers = new List<BaseRoomPacker>();
			foreach (BaseDoorPacker baseDoorPacker in this.m_lstDoorPackers)
			{
				foreach (BaseRoomPacker baseRoomPacker in baseDoorPacker.LstConctRooms)
				{
					if (this.IfBaseRoomPackerIsNear(baseRoomPacker))
					{
						this.m_lstNearRoomPackers.Add(baseRoomPacker);
					}
				}
			}
			this.m_lstNearRoomPackers = this.m_lstNearRoomPackers.Distinct<BaseRoomPacker>().ToList<BaseRoomPacker>();
		}

		private bool IfBaseRoomPackerIsNear(BaseRoomPacker inputRoomPacker)
		{
			bool result;
			try
			{
				if (inputRoomPacker.ThisRoom.IsPointInRoom(this.m_thisLocationPoint) || -1 != Geometry.PointInPloygon(this.m_lstCurves, inputRoomPacker.ThisLocation))
				{
					result = false;
				}
				else
				{
					result = true;
				}
			}
			catch
			{
				result = false;
			}
			return result;
		}

		private Element m_thisElement;

		private double m_dThisArea;

		private XYZ m_thisLocationPoint;

		private List<Curve> m_lstCurves;

		private List<BaseDoorPacker> m_lstDoorPackers;

		private List<BaseRoomPacker> m_lstNearRoomPackers;
	}
}
